﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using System.IO;
using Bingosoft.Common.Logging;

namespace HHMMS.FileServer
{
    /// <summary>
    /// 实现一个HTTP处理程序，用于在web应用程序中下载文件服务器上的文件
    /// 需在web应用程序中的web.config中增加相应的配置。
    /// </summary>
	public class DownloadHandler : IHttpHandler
	{
		// Fields
		private static readonly ILog log = LogManager.GetCurrentClassLogger();

		// Methods
        public void ProcessRequest(HttpContext context)
        {
            //真实文件名
            string fileName = context.Request.QueryString["name"];

            //文件服务器上的文件路径
            string filePath = context.Request.QueryString["path"];

            try
            {
                //文件实际在磁盘的路径
                string savePath = context.Server.MapPath("~/").TrimEnd('\\') + "\\" + filePath.Replace("/", "\\").TrimStart('\\');

                //获取请求的响应并输出到客户端
                using (FileStream file = new FileStream(savePath, FileMode.Open, FileAccess.Read))
                {
                    context.Response.Clear();
                    context.Response.Buffer = true;
                    context.Response.AddHeader("Content-Disposition", "attachment;filename=" + context.Server.UrlPathEncode(fileName));
                    using (BinaryReader dr = new BinaryReader(file))
                    {
                        int blockSize = 1024 * 64, count = 0;
                        byte[] buffer = new byte[blockSize];
                        while ((count = dr.Read(buffer, 0, blockSize)) > 0)
                        {
                            context.Response.OutputStream.Write(buffer, 0, count);
                            context.Response.Flush(); 
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error(" 下载文件错误：" + filePath, ex);
                context.Response.Clear();
                context.Response.Write(ex.Message);
                context.Response.End();
            }
        }

		// Properties
		public bool IsReusable
		{
			get
			{
				return true;
			}
		}
	}
}
